/*
 * @Author: shiguo
 * @Date: 2022-05-17 15:22:06
 * @LastEditors: shiguo
 * @LastEditTime: 2023-09-01 08:32:32
 * @FilePath: /@aks-dev/taro-h5/lib/AnimationModal/index.tsx
 */

import * as  React from "react";
import { View } from '@tarojs/components'
import { AnimationModalProps } from '../../types/AnimationModal'


type StyleProp = {
    containerStyle?: React.CSSProperties;
    wrapperStyle?: React.CSSProperties;
}
type StyleReducerProp = (state: StyleProp, action: Partial<StyleProp>) => StyleProp




export const AnimationModal: React.ForwardRefExoticComponent<
    React.PropsWithoutRef<AnimationModalProps>
    & React.RefAttributes<AnimationModalProps.RefAttributes>
>
    = React.forwardRef((props, ref) => {
        const {
            animationType = 'from-bottom',
            mask = false
        } = props || {}

        const [styleState, styleDispatch] = React.useReducer<StyleReducerProp>(
            (state, action) => ({ ...state, ...action }),
            {
                containerStyle: styles.container,
                wrapperStyle:
                    Object.assign(animationType == 'from-bottom' ? {
                        top: '100%',
                        width: '100%',
                    } : {
                        transform: 'scale(0.5)',
                    }, styles.wrapper)

            })


        const init = React.useCallback(() => ({ show, hide, setData, getData }), [])
        React.useImperativeHandle<unknown, AnimationModalProps.RefAttributes>(ref, init, [styleState])
        const dataRef = React.useRef<any>()


        const setData = (data?: any) => {
            dataRef.current = data
            return init()
        }

        const getData = () => dataRef.current


        const show = () => {
            styleDispatch({
                containerStyle: {
                    ...styleState.containerStyle,
                    visibility: 'visible',
                    transition: 'visibility 0.15s ease-in'
                },
                wrapperStyle:
                    Object.assign({}, styleState.wrapperStyle,
                        animationType == 'from-bottom' ? {
                            transform: `translateY(-${wrapperRef.current?.clientHeight}px)`,
                            transition: 'transform 0.35s ease-in'
                        } : {
                            transform: 'scale(1)',
                            transition: 'transform 0.35s ease'
                        })

            })

            return init()
        }

        const hide = () => {
            styleDispatch({
                containerStyle: {
                    ...styleState.containerStyle,
                    visibility: 'hidden',
                    transition: 'visibility 0.15s ease'
                },
                wrapperStyle: Object.assign({}, styleState.wrapperStyle,
                    animationType == 'from-bottom' ? {
                        transform: 'translateY(0px)',
                        transition: 'transform 0.35s ease-out'
                    } : {
                        transform: 'scale(0.5)',
                        transition: 'transform 0.35s ease'
                    })
            })

            return init()
        }

        const wrapperRef = React.useRef<HTMLElement>()
        return (
            <View style={Object.assign({}, styleState.containerStyle, props.style)} onClick={e => {
                if (!mask) {
                    e.stopPropagation()
                    hide()
                }
            }}>
                <View
                    style={styleState.wrapperStyle}

                    ref={wrapperRef} onClick={e => {
                        e.stopPropagation();
                    }}>
                    {props.children}
                </View>
            </View>
        )
    })



const styles: Record<string, React.CSSProperties> = {
    container: {
        position: 'fixed',
        zIndex: 99999,
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
        width: '100vw',
        height: '100vh',
        display: 'flex',
        flexDirection: 'column',
        backgroundColor: '#00000055',
        visibility: 'hidden',
        overflow: 'hidden',
        justifyContent: 'center',
        alignItems: 'center'
    },
    wrapper: {
        position: 'absolute',
        display: 'flex',
        flexDirection: 'column',
        // backgroundColor: 'white'
    },
}
